package com.study.concurrentprogramming.ref;

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.LinkedList;
import java.util.concurrent.TimeUnit;

/**
 * @Description : 弱引用
 * @Author : xxx
 * @Version : V1.0.0
 * @Date : 2021/9/22 20:35
 */
public class WeakRefTest {
    // gc回收对象后，会把弱引用信息加入指定的引用队列，用来跟踪对象的回收信息
    private static ReferenceQueue<VeryBig> queue = new ReferenceQueue<>();

    private static void checkQueue() {
        Reference<? extends VeryBig> reference = null;
        while ((reference = queue.poll()) != null) {
            System.out.println("in queue : " + ((VeryBigWeakReference) reference).id);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        LinkedList<WeakReference<VeryBig>> weakList = new LinkedList<>();
        // VeryBig veryBig = new VeryBig("Weak " + i);
        weakList.add(new VeryBigWeakReference(new VeryBig("Weak"), queue));
        System.out.println("create weak " + weakList.getLast());

        // 使强引用失效，否则veryBig对象因为存在强引用不会被回收
        // veryBig = null;
        System.gc();
        // 用来等待回收完成
        TimeUnit.SECONDS.sleep(6);
        checkQueue();
    }
}

class VeryBig {
    public String id;

    // 占用空间，让GC回收
    byte[] b = new byte[2 * 1024];

    public VeryBig(String id) {
        this.id = id;
    }

    protected void finalize() {
        System.out.println("finalizing VeryBig " + id);
    }
}

class VeryBigWeakReference extends WeakReference<VeryBig> {

    public String id;

    public VeryBigWeakReference(VeryBig big, ReferenceQueue<VeryBig> queue) {
        super(big, queue);
        this.id = big.id;
    }

    protected void finalize() {
        System.out.println("finalizing VeryBigWeakReference " + id);
    }

}